package com.miplus.ccrm.core.service.strategy;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.miplus.ccrm.common.CmdResVo;
import com.miplus.ccrm.common.JPubUtils;
import com.miplus.ccrm.core.controller.vo.strategy.*;
import com.miplus.ccrm.core.mapper.CfgActivityExecdayMapper;
import com.miplus.ccrm.core.pojo.*;
import com.miplus.ccrm.core.mapper.CfgActivityMapper;
import com.miplus.ccrm.core.pojo.model.AutoDistribute;
import com.miplus.ccrm.core.service.conf.FiDistbatchHistService;
import com.miplus.ccrm.core.service.crd.FiCreditcasesHistService;
import com.miplus.ccrm.core.service.crd.FiCreditcasesService;
import com.miplus.ccrm.core.utils.EnumFiCaseQueue;
import com.miplus.ccrm.core.utils.EnumFiCaseStatus;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
* @author pc
* @description 针对表【cfg_activity(自动分案管理表)】的数据库操作Service实现
* @createDate 2024-03-22 17:43:40
*/
@Service
public class CfgActivityServiceImpl extends MPJBaseServiceImpl<CfgActivityMapper, CfgActivity>
    implements CfgActivityService{
    @Resource
    private CfgActivityOthergrplinkService cfgActivityOthergrplinkService;
    @Resource
    private CfgActivityQuerylinkService cfgActivityQuerylinkService;
    @Resource
    private CfgActivityExecdayMapper cfgActivityExecdayMapper;

    @Resource
    private FiCreditcasesService fiCreditcasesService;

    @Resource
    private FiCreditcasesHistService fiCreditcasesHistService;

    @Resource
    private FiDistbatchHistService fiDistbatchHistService;



    @Override
    public IPage<ActivityResVo> cfgActivityList(ActivityReqVo paras)
    {
        return selectJoinListPage(new Page<>(paras.getPageNum(), paras.getPageSize()),
                ActivityResVo.class,
                new MPJLambdaWrapper<CfgActivity>()
                        .selectAs("fun_getnames('BUSINESS.TYPE',t.businesstype)",ActivityResVo::getBusinesstypedsc)
                        .selectAs("fun_getnames('ACTIVITY.QUERY.DISTYPE',t.distype)",ActivityResVo::getDistypedsc)
                        .selectAs("concat(t.overday1,'-',t.overday2)",ActivityResVo::getOverday)
                        .selectAs("concat(t.availableday1,'~',t.availableday2)",ActivityResVo::getAvailableday)
                        .selectAll(CfgActivity.class)
                        .like(JPubUtils.IsNotEmpty(paras.getName()),"name",paras.getName())
                        .eq(paras.getStatus()!=null,"status",paras.getStatus())
                        .orderByAsc("t.rank")
        );
    }

    @Override
    public CmdResVo cfgActivityUpdate(String $usrid, ActivityEditVo paras)
    {
        CfgActivity def=new CfgActivity();
        BeanUtils.copyProperties(paras,def);
        def.setMddt(new Date());
        def.setMdusr($usrid);
        //2024-08-05
        int ret=baseMapper.update(def,new UpdateWrapper<CfgActivity>()
                .lambda()
                .eq(CfgActivity::getActivityid,paras.getActivityid())
                .set(JPubUtils.IsEmpty(paras.getCity()),CfgActivity::getCity,null)
                .set(JPubUtils.IsEmpty(paras.getBusinesstype()),CfgActivity::getBusinesstype,null)
                .set(JPubUtils.IsEmpty(paras.getMthsOdue()),CfgActivity::getMthsOdue,null)
                .set(JPubUtils.IsEmpty(paras.getMthsOdue2()),CfgActivity::getMthsOdue2,null)
                .set(JPubUtils.IsEmpty(paras.getOverday1()),CfgActivity::getOverday1,null)
                .set(JPubUtils.IsEmpty(paras.getOverday2()),CfgActivity::getOverday2,null)
                .set(JPubUtils.IsEmpty(paras.getGrpid()),CfgActivity::getGrpid,null)
                .set(JPubUtils.IsEmpty(paras.getCusttags()),CfgActivity::getCusttags,null)
                .set(JPubUtils.IsEmpty(paras.getAcctFlevel()),CfgActivity::getAcctFlevel,null)
        );

        cfgActivityOthergrplinkService.getBaseMapper().delete(
                new QueryWrapper<CfgActivityOthergrplink>().eq("activityid",paras.getActivityid())
        );
        cfgActivityExecdayMapper.delete(
                new QueryWrapper<CfgActivityExecday>().eq("activityid",paras.getActivityid())
        );
        updateLinkTable(paras.getActivityid(),paras);

        return new CmdResVo(ret,def.getActivityid().toString());
    }

    @Override
    public CmdResVo cfgActivityInsert(String $usrid,ActivityEditVo paras)
    {
        CfgActivity def=new CfgActivity();

        BeanUtils.copyProperties(paras,def);
        int max=getActivityMaxRank();
        //def.setRank(max);
        def.setCrdt(new Date());
        def.setCrusr($usrid);
        def.setMddt(new Date());
        def.setMdusr($usrid);
        int ret=baseMapper.insert(def);

        //for TDSQL
        baseMapper.updateRank(def.getActivityid(),max);

        updateLinkTable(def.getActivityid(),paras);
        return new CmdResVo(ret,def.getActivityid().toString());
    }

    private int getActivityMaxRank()
    {
        Long num=baseMapper.selectCount(new QueryWrapper<>());
        if(num>0) {
            List<Integer> max = baseMapper.getMaxRank();
            if (JPubUtils.IsEmpty(max))
                return 1;
            return max.get(0) + 1;
        }
        else return 1;
    }

    private void updateLinkTable(Integer activityid,ActivityEditVo paras)
    {
        cfgActivityOthergrplinkService.remove(
                new LambdaQueryWrapper<CfgActivityOthergrplink>()
                        .eq(CfgActivityOthergrplink::getActivityid,activityid));
        if(JPubUtils.IsNotEmpty(paras.getOutgrplist())){
            for(ActGrplinkVo g : paras.getOutgrplist()){
                CfgActivityOthergrplink l=new CfgActivityOthergrplink();
                l.setActivityid(activityid);
                l.setGrpid(g.getGrpid());
                l.setRadio(g.getRadio());
                cfgActivityOthergrplinkService.getBaseMapper().insert(l);
            }
        }
        if(JPubUtils.IsNotEmpty(paras.getExecdaylist())){
            for(ActExecDayVo d : paras.getExecdaylist()){
                CfgActivityExecday f=new CfgActivityExecday();
                f.setActivityid(activityid);
                Date day=JPubUtils.StringToDate(d.getDistDTime());
                if(day!=null) {
                    f.setExecdate(JPubUtils.StringToDate(d.getDistDTime()));
                    f.setRecydate(JPubUtils.StringToDate(d.getRecyDTime()));
                    cfgActivityExecdayMapper.insert(f);
                }
            }
        }
    }

    @Override
    public CmdResVo cfgActivityDelete(int id)
    {
        int ret=baseMapper.deleteById(id);
        cfgActivityOthergrplinkService.getBaseMapper().delete(
                new QueryWrapper<CfgActivityOthergrplink>().eq("activityid",id)
        );
        cfgActivityQuerylinkService.getBaseMapper().delete(
                new QueryWrapper<CfgActivityQuerylink>().eq("activityid",id)
        );
        cfgActivityExecdayMapper.delete(
                new QueryWrapper<CfgActivityExecday>().eq("activityid",id)
        );
        return new CmdResVo(ret,Integer.toString(id));
    }

    @Override
    public CmdResVo upCfgActivity(int activityid)
    {
        //FOR TDSQL
        //CfgActivity f=baseMapper.selectById(activityid);
        CfgActivity f=baseMapper.activitySelectOne(activityid);
        Integer rank=f.getRank();
        if(rank==null||rank<=1){
            return new CmdResVo(0,Integer.toString(activityid));
        }
        //FOR TDSQL
        //rank=rank-1;
        Integer rankold=rank-1;
        //CfgActivity def=new CfgActivity();
        //def.setRank(rank+1);
        //int ret=baseMapper.update(def,
         //           new QueryWrapper<CfgActivity>()
         //           .eq("t.rank",rank)
       // );
        int ret=baseMapper.updateRankAsc(rankold,rank+1);
        //def=new CfgActivity();
        //def.setActivityid(activityid);
        //def.setRank(rank);
        //baseMapper.updateById(def);
        baseMapper.updateRank(activityid,rank);
        return new CmdResVo(ret,Integer.toString(activityid));
    }

    @Override
    public CmdResVo downCfgActivity(int activityid)
    {
        //for TDSQL
        //CfgActivity f=baseMapper.selectById(activityid);
        CfgActivity f=baseMapper.activitySelectOne(activityid);
        Integer rank=f.getRank();
        List<Integer> max=baseMapper.getMaxRank();
        Integer maxrank=max.get(0);
        if(rank==null||rank>=maxrank){
            return new CmdResVo(0,Integer.toString(activityid));
        }
        Integer rankold=rank+1;
        //for tdsql
        //CfgActivity def=new CfgActivity();
        //def.setRank(rank-1);
        //int ret=baseMapper.update(def,
         //       new QueryWrapper<CfgActivity>()
         //               .eq("t.rank",rank)
        //);
        int ret=baseMapper.updateRankAsc(rankold,rank-1);
        //def=new CfgActivity();
        //def.setActivityid(activityid);
        //def.setRank(rank);
        //baseMapper.updateById(def);
        baseMapper.updateRank(activityid,rank);
        return new CmdResVo(ret,Integer.toString(activityid));
    }

    @Override
    public IPage<ActOGrpLinkResVo> activityOutGrpList(ActOGrpLinkReqVo paras)
    {
        return cfgActivityOthergrplinkService.activityOutGrpList(paras);
    }

    @Override
    public List<ActExecDayVo> getActivityExecDay(Integer activityid)
    {
        List<CfgActivityExecday> dateList=cfgActivityExecdayMapper.selectList(new QueryWrapper<CfgActivityExecday>()
                    .eq("activityid",activityid)
                    .select("execdate","recydate")
                    .orderByAsc("id")
        );
        List<ActExecDayVo> list=new ArrayList<>();
        for(CfgActivityExecday g : dateList){
            ActExecDayVo vo=new ActExecDayVo();
            vo.setDistDTime(JPubUtils.DateToString(g.getExecdate()));
            vo.setRecyDTime(JPubUtils.DateToString(g.getRecydate()));
            list.add(vo);
        }
        return list;
    }

//    public void autoDistribute() {
//        List<CfgActivity> list = list(new QueryWrapper<CfgActivity>()
//                .eq("status", 1)  //<=  >=
//                .and(i -> i.le("availableday1", LocalDate.now()).or().isNull("availableday1")) //mysql使用ifnull
//                .and(i -> i.ge("availableday2", LocalDate.now()).or().isNull("availableday2"))
//                .and(i -> i.isNull("distdaymode").or().eq("distdaymode", "0").or().exists("select 1 from cfg_activity_execday cae where cfg_activity.activityid=cae.activityid and cae.execdate=CURRENT_DATE"))
//                .orderByAsc("rank")
//        );
//        XxlJobHelper.log("XXXL-JOB-autoDistribute 分配模版:" + list.size() + "个");
//
//        // 分配案件
//        searchCases(list);
//    }
//    private void searchCases(List<CfgActivity> list) {
//        list.forEach(item -> {
//            try {
//                Random random = new Random();
//                int id = random.nextInt(100);
//                // 获取当前日期和时间
//                LocalDateTime currentDateTime = LocalDateTime.now();
//                String formatter = currentDateTime.format(DateTimeFormatter.ofPattern("yyMMddHHmm"));
//                String batchid = "A" + formatter + String.format("%03d", id);
//                Date distdt = new Date();
//
//                Date binddt = null;
//                long diffInDays = 0;
//                // 案件自动回收时间
//                if (Objects.equals(item.getDistdaymode(), "1")) {
//                    CfgActivityExecday cfgActivityExecday = cfgActivityExecdayMapper.selectOne(new QueryWrapper<CfgActivityExecday>().eq("activityid", item.getActivityid()).eq("execdate", LocalDate.now()));
//                    binddt = cfgActivityExecday.getRecydate();
//                    long diffInMillies = Math.abs(cfgActivityExecday.getRecydate().getTime() - cfgActivityExecday.getExecdate().getTime());
//                    diffInDays = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS);
//                } else {
//                    Calendar calendar = Calendar.getInstance();
//                    calendar.setTime(new Date());
//                    calendar.add(Calendar.DATE, item.getBindday());
//                    binddt = calendar.getTime();
//                }
//
//                // 查询自定义条件
//                List<QueryLink> querylink = cfgActivityQuerylinkMapper.selectJoinList(QueryLink.class, new MPJLambdaWrapper<CfgActivityQuerylink>()
//                        .leftJoin(CfgActivityQuerydatacol.class, "cd", CfgActivityQuerydatacol::getSplicecol, CfgActivityQuerylink::getSplicecol)
//                        .selectAll(CfgActivityQuerylink.class)
//                        .selectAll(CfgActivityQuerydatacol.class)
//                        .eq(CfgActivityQuerylink::getStatus, 1)
//                        .eq(CfgActivityQuerylink::getActivityid, item.getActivityid())
//                        .orderByAsc("type"));
//                XxlJobHelper.log("XXL-JOB-autoDistribute 自定义条件:" + querylink.size() + "条.");
//                System.out.println("querylink: " + querylink.size() + "条");
//
//                // 定义案件对查询条件
//                MPJLambdaWrapper<FiCreditcases> mpjLambdaWrapper = new MPJLambdaWrapper<>();
//                mpjLambdaWrapper.innerJoin(CreditAccount.class, "cda", CreditAccount::getAcct, FiCreditcases::getCreditAcct);
//                mpjLambdaWrapper.leftJoin(CreditAccountBalance.class, "cdb", CreditAccountBalance::getAcct, FiCreditcases::getCreditAcct);
//                mpjLambdaWrapper.leftJoin(ConCustomer.class, "cu", ConCustomer::getCustomernumber, FiCreditcases::getCustomernumber);
//                //mpjLambdaWrapper.leftJoin(CreditCard.class, "cdc", CreditCard::getAcct, FiCreditcases::getCreditAcct);
//                mpjLambdaWrapper.selectAll(FiCreditcases.class);
//                mpjLambdaWrapper.select(CreditAccount::getMthsOdue);
//                mpjLambdaWrapper.select(CreditAccountBalance::getSettledBillAmt, CreditAccountBalance::getSettledBillPrin, CreditAccountBalance::getSettledBillInt, CreditAccountBalance::getSettledBillFee, CreditAccountBalance::getPenchgAcc);
//                mpjLambdaWrapper.eq("t.ccc", "O");
//                mpjLambdaWrapper.and(i -> i.le("t.stopautodistenddt", LocalDateTime.now()).or().isNull("t.stopautodistenddt"));
//                mpjLambdaWrapper.apply("fi_hasStopCall(t.creditcaseid,'CASE')<=0");
//
//                if (item.getMthsOdue() != null) {
////                String[] mthsOdue = item.getMthsOdue().split(",");
////                List<Integer> ids = Arrays.stream(mthsOdue)
////                        .map(Integer::parseInt)
////                        .collect(Collectors.toList());
////                mpjLambdaWrapper.in("cda.mths_odue", ids);
//                    mpjLambdaWrapper.ge("cda.mths_odue", item.getMthsOdue());
//                }
//                if (item.getMthsOdue2() != null) {
//                    mpjLambdaWrapper.le("cda.mths_odue", item.getMthsOdue2());
//                }
//                if (item.getBusinesstype() != null && !item.getBusinesstype().isEmpty()) {
//                    mpjLambdaWrapper.eq("t.prodtype", item.getBusinesstype());
//                }
//                if (item.getCusttags() != null && !item.getCusttags().isEmpty()) {
//                    String tags = item.getCusttags().replace(",", "','");
//                    mpjLambdaWrapper.exists("select 1 from con_customertag ct where ct.custid=t.customernumber and ct.id in ('" + tags + "')");
//                }
//                if (item.getCity() != null && !item.getCity().isEmpty()) {
//                    String provinces = item.getCity().replace(",", "','");
//                    mpjLambdaWrapper.exists("select 1 from con_address ca where ca.customernumber = t.customernumber and ca.province in ('" + provinces + "')");
//                }
//
//                querylink.forEach(x -> {
//                    if (x.getMethod() != null && x.getSplicecol() != null && x.getColvalue() != null && x.getType() == 1) {
//                        switch (x.getMethod()) {
//                            case "=":
//                                mpjLambdaWrapper.eq(x.getSplicecol(), x.getColvalue());
//                                break;
//                            case "!=":
//                                mpjLambdaWrapper.ne(x.getSplicecol(), x.getColvalue());
//                                break;
//                            case "like":
//                                mpjLambdaWrapper.like(x.getSplicecol(), x.getColvalue());
//                                break;
//                            case ">":
//                                mpjLambdaWrapper.gt(x.getSplicecol(), x.getColvalue());
//                                break;
//                            case "<":
//                                mpjLambdaWrapper.lt(x.getSplicecol(), x.getColvalue());
//                                break;
//                            case ">=":
//                                mpjLambdaWrapper.ge(x.getSplicecol(), x.getColvalue());
//                                break;
//                            case "<=":
//                                //mpjLambdaWrapper.le(x.getSplicecol(), x.getColvalue());
//                                mpjLambdaWrapper.le(x.getSplicecol(), Objects.equals(x.getDatatype(), "numeric") ? new BigDecimal(x.getColvalue()) : x.getColvalue());
//                                break;
//                        }
//                    }
//                });
//                long orcount = querylink.stream().filter(queryLink -> queryLink.getType() == 2).count();
//                XxlJobHelper.log("XXL-JOB-autoDistribute 自定义条件type=2:" + orcount + "条.");
//                if (orcount > 0) {
//                    mpjLambdaWrapper.and(orWrapper -> {
//                        querylink.forEach(x -> {
//                            if (x.getMethod() != null && x.getSplicecol() != null && x.getColvalue() != null && x.getType() == 2) {
//                                switch (x.getMethod()) {
//                                    case "=":
//                                        orWrapper.or().eq(x.getSplicecol(), x.getColvalue());
//                                        break;
//                                    case "!=":
//                                        orWrapper.or().ne(x.getSplicecol(), x.getColvalue());
//                                        break;
//                                    case "like":
//                                        orWrapper.or().like(x.getSplicecol(), x.getColvalue());
//                                        break;
//                                    case ">":
//                                        orWrapper.or().gt(x.getSplicecol(), x.getColvalue());
//                                        break;
//                                    case "<":
//                                        orWrapper.or().lt(x.getSplicecol(), x.getColvalue());
//                                        break;
//                                    case ">=":
//                                        orWrapper.or().ge(x.getSplicecol(), x.getColvalue());
//                                        break;
//                                    case "<=":
//                                        orWrapper.or().le(x.getSplicecol(), x.getColvalue());
//                                        break;
//                                }
//                            }
//                        });
//                    });
//                }
//
//                // 过滤符合条件的案件
//                List<CaseJoinAcct> caselist = fiCreditcasesMapper.selectJoinList(CaseJoinAcct.class, mpjLambdaWrapper);
//
//                System.out.println("caselist: " + caselist);
//                XxlJobHelper.log("XXL-JOB-autoDistribute 符合条件的案件:" + caselist.size() + "条.");
//                XxlJobHelper.log("");
//
//                int count = caselist.size();
//                int sumamount = caselist.stream().map(CaseJoinAcct::getSettledBillAmt).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add).intValue();
//                BigDecimal sum_amount = caselist.stream().map(CaseJoinAcct::getSettledBillAmt).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
//
//                if (count > 0) {
//                    List<CfgActivityOthergrplink> groups = cfgActivityOthergrplinkService.list(new QueryWrapper<CfgActivityOthergrplink>()
//                            .eq("activityid", item.getActivityid())
//                            .orderByDesc("radio"));
//
//                    System.out.println("groups: " + groups.size() + "条");
//                    XxlJobHelper.log("XXL-JOB-autoDistribute 委外机构:" + groups.size() + "条.");
//                    if (groups.size() > 0) {
//                        int type = item.getDistype2();
//                        // 1=平均分配 2=按金额比例分配 3=按数量比例分配
//                        switch (type) {
//                            case 1:
//                                disUsersToCases(caselist, groups);
//                                //preDistCaseByAvg(caselist,groups,1);
//                                break;
//                            case 2:
//                            case 3:
//                                List<AutoDistribute> grplist = new ArrayList<>();
//                                AutoDistribute model = null;
//                                for (int i = 0; i < (long) groups.size(); i++) {
//                                    model = new AutoDistribute();
//                                    model.setSysGrp(groups.get(i));
//                                    model.setNum(0);
//                                    model.setAmount(BigDecimal.valueOf(0));
//                                    grplist.add(model);
//                                }
//
//                                caselist.forEach(x -> {
//                                    grplist.sort(Comparator.comparing(AutoDistribute::getNum));
//                                    XxlJobHelper.log("XXL-JOB-autoDistribute, 排序grplist:" + grplist);
//                                    x.setDistributorid(item.getActivityid());
//                                    x.setSendtodept(grplist.get(0).getSysGrp().getGrpid());
//                                    if (x.getSettledBillAmt() != null) {
//                                        grplist.get(0).setAmount(x.getSettledBillAmt().add(grplist.get(0).getAmount()));
//                                    }
//                                    grplist.get(0).setNum(grplist.get(0).getNum() + 1);
//                                    if (item.getDistype2() == 3) { // 3按数量分配 2按金额分配
//                                        if (grplist.get(0).getNum() >= count * (grplist.get(0).getSysGrp().getRadio()) / 100.00) {
//                                            grplist.remove(0);
//                                        }
//                                    } else {
//                                        if (grplist.get(0).getAmount().intValue() >= sumamount * (grplist.get(0).getSysGrp().getRadio()) / 100.00) {
//                                            grplist.remove(0);
//                                        }
//                                    }
//                                });
//                                break;
//                        }
//
//                        List<FiCreditcasesHist> histlist = new ArrayList<>();
//                        Date finalBinddt = binddt;
//                        caselist.forEach(x -> {
//                            x.setStatus(1);
//                            x.setStatusdt(new Date());
//                            x.setCcc("Q");
//                            x.setDistbatchid(batchid);
//                            x.setDistributetype(1);
//                            x.setDistusr("system");
//                            x.setDistdt(distdt);
//                            x.setMdusr("system");
//                            x.setMddt(new Date());
//                            x.setBindenddt(finalBinddt);
//
////                        // 案件自动回收时间
////                        if (Objects.equals(item.getDistdaymode(), "1")) {
////                            CfgActivityExecday cfgActivityExecday = cfgActivityExecdayMapper.selectOne(new QueryWrapper<CfgActivityExecday>().eq("activityid", item.getActivityid()).eq("execdate", LocalDate.now()));
////                            x.setBindenddt(cfgActivityExecday.getRecydate());
////                        } else {
////                            Calendar calendar = Calendar.getInstance();
////                            calendar.setTime(new Date());
////                            calendar.add(Calendar.DATE, item.getBindday());
////                            x.setBindenddt(calendar.getTime());
////                        }
//
//                            FiCreditcases cCases = new FiCreditcases();
//                            // 将x属性复制到新对象cCases中
//                            BeanUtils.copyProperties(x, cCases);
//                            cCases.setMthsOdue(x.getMthsOdue());
//                            cCases.setOdudPrin(x.getSettledBillAmt());
//                            cCases.setOverPrin(x.getSettledBillPrin());
//                            cCases.setInterestFee(x.getSettledBillInt());
//                            cCases.setPenchgAcc(x.getPenchgAcc());
//                            cCases.setOthExpense(x.getSettledBillFee());
//
//                            fiCreditcasesService.updateById(cCases);
//
//                            FiCreditcases fiCase = fiCreditcasesMapper.selectOne(new QueryWrapper<FiCreditcases>().eq("credit_acct", x.getCreditAcct()));
//                            FiCreditcasesHist fiCreditcasesHist = new FiCreditcasesHist();
//                            BeanUtils.copyProperties(fiCase, fiCreditcasesHist);
//                            histlist.add(fiCreditcasesHist);
//                            fiCreditcasesMapper.update(null, new UpdateWrapper<FiCreditcases>()
//                                    .lambda()
//                                    .eq(FiCreditcases::getCreditcaseid, x.getCreditcaseid())
//                                    .set(FiCreditcases::getAssigntype, null)
//                                    .set(FiCreditcases::getAssignusr, null)
//                                    .set(FiCreditcases::getAssigndt, null)
//                                    .set(FiCreditcases::getSendtousr, null)
//                            );
//                        });
//                        fiCreditcasesHistService.saveBatch(histlist);
//                        // 添加分案批次历史记录表
//                        FiDistbatchHist fiDistbatchHist = new FiDistbatchHist();
//                        fiDistbatchHist.setBatchid(batchid);
//                        fiDistbatchHist.setBatchname(item.getRemark() + batchid);
//                        fiDistbatchHist.setBinddays(Objects.equals(item.getDistdaymode(), "1") ? (int) diffInDays : item.getBindday());
//                        fiDistbatchHist.setActiontype("1");
//                        fiDistbatchHist.setActiondt(new Date());
//                        fiDistbatchHist.setActionusr("system");
//                        fiDistbatchHist.setOkcnt(count);
//                        fiDistbatchHist.setDistcnt(count);
//                        fiDistbatchHist.setDistamt(sum_amount);
//                        fiDistbatchHist.setDistmode(item.getDistype2() == 1 ? 1 : 5);
//                        fiDistbatchHistService.save(fiDistbatchHist);
//                    } else {
//                       // XxlJobHelper.log("XXL-JOB-autoDistribute 请配置自动分案团队.");
//                    }
//                }
//            } catch (Exception e) {
//                //XxlJobHelper.log("XXL-JOB-autoDistribute, 错误日志:" + e + ">>>>>【异常列】：" + item);
//            }
//        });
//    }

    private void disUsersToCases(List<FiCreditcases> caseList, List<CfgActivityOthergrplink> userList, Integer diableLastGep) {

        int totalCases = caseList.size(),
                totalUsers = userList.size(),
                casesPerUser = totalCases / totalUsers,   // 计算每个用户应该分配的案例数量
                extraCases = totalCases % totalUsers,     // 计算余下的案例数量
                caseIndex = 0;

        Collections.shuffle(userList);
        for (CfgActivityOthergrplink item : userList) {
            int assignedCases = casesPerUser + (extraCases > 0 ? 1 : 0); // 每个用户应该分配的案例数量
            for (int i = 0; i < assignedCases; i++) {
                caseList.get(caseIndex).setSendtodept(item.getGrpid());
                caseIndex++;
            }
            extraCases--; // 余下的案例数量减少
        }
    }

    /**
     * 根据策略定义，自动分配。
     * @param cfgRuleTaskSteps
     * @param cfgActivity
     * @return
     */

    @Override
    public CmdResVo distribute(String usrId, CfgRuleTaskSteps cfgRuleTaskSteps, CfgActivity cfgActivity,String sql)
    {
        if( cfgRuleTaskSteps == null || cfgActivity == null)
        {
            return new CmdResVo(-1,"参数不正确");
        }
//        String sql = cfgRuleTaskSteps.getFilterSql();
//        if(StringUtils.isEmpty(sql))
//            sql = " 1=1 ";
//        //客户黑名单。
//        if( cfgRuleTaskSteps.getExcludeBlack() == 1)
//            sql += " and not exists (select 1 from con_blacklist cbl where cbl.customernumber = cu.customernumber and cbl.type = 1 )";
//
//        if( cfgRuleTaskSteps.getExcludeWhite() == 1)
//            sql += " and not exists ( select 1 from con_blacklist cbl where cbl.customernumber = cu.customernumber and cbl.type = 2 )";
//
//        if( cfgRuleTaskSteps.getExcludeStop() == 1)
//            //sql += " and fi_hasstopcall(fc.creditcaseid,'CASE')=0 ";
//             sql += "  and  not exists( SELECT 1  \n" +
//                     "    FROM fi_stopcall s  \n" +
//                     "    WHERE s.stopkey = fc.creditcaseid and s.stoptype = 'CASE' AND s.status = 2 )";
//        if(cfgRuleTaskSteps.getExcludeCustomerStop() == 1)
//            //sql += " and fi_hasstopcall(cu.customernumber,'CUSTOMER')=0 ";
//            sql += "  and  not exists( SELECT 1  \n" +
//                    "    FROM fi_stopcall s  \n" +
//                    "    WHERE s.stopkey = cu.customernumber and s.stoptype = 'CUSTOMER' AND s.status = 2 )";

//        List<FiCreditcases> caselist = fiCreditcasesService.getDistributeCollectList(sql);
//        int count = caselist.size();
////            int sumamount = caselist.stream().map(FiCreditcases::getOdudPrin).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add).intValue();
////            BigDecimal sum_amount = caselist.stream().map(FiCreditcases::getOdudPrin).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
//        if (count > 0) {
//            List<CfgActivityOthergrplink> groups = cfgActivityOthergrplinkService.list(new QueryWrapper<CfgActivityOthergrplink>()
//                    .eq("activityid", cfgActivity.getActivityid())
//                    .orderByDesc("radio"));
//            System.out.println("groups: " + groups.size() + "条");
//            if (groups.size() > 0)
//            {
//                return DistributeToGrp(cfgRuleTaskSteps.getRuleStepId().toString(),"system", cfgActivity,caselist,groups,1);
//            }
//        }
        return fiCreditcasesService.DistributeToGrpByRule(usrId, cfgRuleTaskSteps.getRuleStepId().toString(), cfgActivity, sql);
        //return new CmdResVo(0);
    }


    public CmdResVo DistributeToGrp(String ruleStepId, String usrId, CfgActivity cfgActivity, List<FiCreditcases> caselist,List<CfgActivityOthergrplink> groups,Integer distributeType)
    {

        int count = caselist.size();
        int sumamount = caselist.stream().map(FiCreditcases::getOverdueTotalamt).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add).intValue();
        BigDecimal sum_amount = caselist.stream().map(FiCreditcases::getOverdueTotalamt).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);

        // 获取当前日期和时间
        Random random = new Random();
        int id = random.nextInt(100);
        LocalDateTime currentDateTime = LocalDateTime.now();
        String formatter = currentDateTime.format(DateTimeFormatter.ofPattern("yyMMddHHmm"));
        String batchid = "A" + formatter + String.format("%03d", id);
        Date distdt = new Date();
        Date binddt = null;
        long diffInDays = 0;
        // 案件自动回收时间
        if (Objects.equals(cfgActivity.getDistdaymode(), "1")) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.add(Calendar.MONTH, cfgActivity.getAftermonth());
            calendar.set(Calendar.DATE,Integer.parseInt(cfgActivity.getFixday()));
            binddt = calendar.getTime();
            long diffInMillies = Math.abs(calendar.getTime().getTime() - distdt.getTime());
            diffInDays = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS);

        } else {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.add(Calendar.DATE, cfgActivity.getBindday());
            binddt = calendar.getTime();
        }

        if (groups.size() > 0) {
            int type = cfgActivity.getDistype2();
            // 1=平均分配 2=按金额比例分配 3=按数量比例分配
            switch (type) {
                case 1:
                    disUsersToCases(caselist, groups, cfgActivity.getDisablelastgrp());
                    //preDistCaseByAvg(caselist,groups,1);
                    break;
                case 2:
                case 3:
                    List<AutoDistribute> grplist = new ArrayList<>();
                    AutoDistribute model = null;
                    for (int i = 0; i < (long) groups.size(); i++) {
                        model = new AutoDistribute();
                        model.setSysGrp(groups.get(i));
                        model.setNum(0);
                        model.setAmount(BigDecimal.valueOf(0));
                        grplist.add(model);
                    }

                    caselist.forEach(x -> {
                        grplist.sort(Comparator.comparing(AutoDistribute::getNum));
                        //XxlJobHelper.log("XXL-JOB-autoDistribute, 排序grplist:" + grplist);
                        x.setDistributorid(Long.parseLong(cfgActivity.getActivityid().toString()));
                        x.setSendtodept(grplist.get(0).getSysGrp().getGrpid());
                        if (x.getOverPrin() != null) {
                            grplist.get(0).setAmount(x.getOverdueTotalamt().add(grplist.get(0).getAmount()));
                        }
                        grplist.get(0).setNum(grplist.get(0).getNum() + 1);
                        if (cfgActivity.getDistype2() == 3) { // 3按数量分配 2按金额分配
                            if (grplist.get(0).getNum() >= count * (grplist.get(0).getSysGrp().getRadio()) / 100.00) {
                                grplist.remove(0);
                            }
                        } else {
                            if (grplist.get(0).getAmount().intValue() >= sumamount * (grplist.get(0).getSysGrp().getRadio()) / 100.00) {
                                grplist.remove(0);
                            }
                        }
                    });
                    break;
            }

            List<FiCreditcasesHist> histlist = new ArrayList<>();
            Date finalBinddt = binddt;
            caselist.forEach(x -> {
                x.setStatus(EnumFiCaseStatus.Distribute.value);
                x.setStatusdt(new Date());
                x.setCcc(EnumFiCaseQueue.Q.value); //改成在催队列
                x.setDistbatchid(batchid);
                x.setDistributorid(Long.parseLong(ruleStepId));
                x.setDistributetype(distributeType);
                x.setDistusr(usrId);
                x.setDistdt(distdt);
                x.setMdusr(usrId);
                x.setMddt(new Date());
                // 案件自动回收时间
                x.setBindenddt(finalBinddt);
                //设置入催时间
                if(ObjectUtils.isNull(x.getIndt()))
                    x.setIndt(new Date());
                //需要设置队列标签。
                x.setDisttag(cfgActivity.getCaseflag());
                if(cfgActivity.getEffectivedistday() == null)
                    x.setCpStartTime(new Date());
                else
                    x.setCpStartTime(cfgActivity.getEffectivedistday());
                x.setCpEndTime(finalBinddt);

                x.setCpTotalamt(x.getOverdueTotalamt());
                x.setCpAmt(x.getPreRepayPrincipal());
                x.setCpCost(x.getPreRepayFee());
                x.setCpInterest(x.getPreRepayInterest());
                x.setCpOverdueDays(x.getMthsDay());
                //                    //FiCreditcases cCases = new FiCreditcases();
                //                    // 将x属性复制到新对象cCases中
                //                    //BeanUtils.copyProperties(x, cCases);
                //                    cCases.setMthsOdue(x.getMthsOdue());
                //                    cCases.setOdudPrin(x.getSettledBillAmt());
                //                    cCases.setOverPrin(x.getSettledBillPrin());
                //                    cCases.setInterestFee(x.getSettledBillInt());
                //                    cCases.setPenchgAcc(x.getPenchgAcc());
                //                    cCases.setOthExpense(x.getSettledBillFee());

                fiCreditcasesService.updateById(x);

                FiCreditcasesHist fiCreditcasesHist = new FiCreditcasesHist();
                BeanUtils.copyProperties(x, fiCreditcasesHist);
                fiCreditcasesHist.setActiontype(1); //分案
                histlist.add(fiCreditcasesHist);
                //                    fiCreditcasesMapper.update(null, new UpdateWrapper<FiCreditcases>()
                //                            .lambda()
                //                            .eq(FiCreditcases::getCreditcaseid, x.getCreditcaseid())
                //                            .set(FiCreditcases::getAssigntype, null)
                //                            .set(FiCreditcases::getAssignusr, null)
                //                            .set(FiCreditcases::getAssigndt, null)
                //                            .set(FiCreditcases::getSendtousr, null)
                //                    );
            });
            fiCreditcasesHistService.saveBatch(histlist);
            // 添加分案批次历史记录表
            FiDistbatchHist fiDistbatchHist = new FiDistbatchHist();
            fiDistbatchHist.setBatchid(batchid);
            fiDistbatchHist.setBatchname(cfgActivity.getName() + batchid);
            fiDistbatchHist.setBinddays((int) diffInDays);
            fiDistbatchHist.setBindenddt(finalBinddt);
            fiDistbatchHist.setActiontype(distributeType.toString());
            fiDistbatchHist.setActiondt(new Date());
            fiDistbatchHist.setActionusr(usrId);
            fiDistbatchHist.setOkcnt(count);
            fiDistbatchHist.setDistcnt(count);
            fiDistbatchHist.setDistamt(sum_amount);
            fiDistbatchHist.setDistmode(cfgActivity.getDistype2() == 1 ? 1 : 5);
            fiDistbatchHistService.save(fiDistbatchHist);
        }
        return new CmdResVo(count,"OK");
    }

}




